/*
 *      Main.cpp
 *      
 *      Copyright 2009 Daniel Penney <bikedude880@paqsario.tastywaffle.org>
 *      
 *      This program is free software; you can redistribute it and/or modify
 *      it under the terms of the GNU General Public License as published by
 *      the Free Software Foundation; either version 2 of the License, or
 *      (at your option) any later version.
 *      
 *      This program is distributed in the hope that it will be useful,
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *      GNU General Public License for more details.
 *      
 *      You should have received a copy of the GNU General Public License
 *      along with this program; if not, write to the Free Software
 *      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 *      MA 02110-1301, USA.
 */

#include "Pirates.hpp"


// Entry point
int main( int argc, char* argv[] )
{
    Pirates Engine;

	Engine.Init();
	Engine.Start();

	return 0;
}

void Pirates::AdditionalInit()
{
	/// Load and check all image data
	cout << "Loading game data...	";
	tiles = LoadImage( "Res/tiles.png" );
	ship = LoadImage( "Res/ship.png" );
	mast = LoadImage( "Res/mast.png" );
	if( !tiles || !ship || !mast ) {
		cout << endl << "Could not load all images. Please ensure Res folder is populated" << endl;
		exit( 1 );
	}
	cout <<  "[ OK ]" << endl;

	/// Set clip for ship and board tiles
	for( int n = 0; n < 2; n++ ) {
		the_mast_clip[ n ] = GetTileClip( mast, 2, 1 );
		the_mast_clip[ n ].x *= n;
	}

	for( int clip_count = 0; clip_count < 4; clip_count++ ) {
		the_ship_clip[ clip_count ] = GetTileClip( ship, 4, 1 );
		the_ship_clip[ clip_count ].x *= clip_count;
		
		the_tile_clip[ clip_count ] = GetTileClip( tiles, 4, 1 );
		the_tile_clip[ clip_count ].x *= clip_count;
	}

	/// Set other variables

	/// Populate the board
	srand((unsigned)time(0));

	map.initMap( 9, 9 );

	cout << "Adding Units: ";
	cout << "Portals... ";
	units.CreateUnit( PRT, STATIC, 0, 0 );
	units.CreateUnit( PRT, STATIC, map.getMapW(), 0 );
	units.CreateUnit( PRT, STATIC, 0, map.getMapH() );
	units.CreateUnit( PRT, STATIC, map.getMapW(), map.getMapH() );

	cout << "Player... ";
	units.CreateUnit( PLY, (e_unitDir)( (rand() % 7 + 1) ), map.getRandX(), map.getRandY() );

	cout << "Islands... ";
	units.CreateUnit( ISL, STATIC, map.getRandX(), map.getRandY() );
	units.CreateUnit( ISL, STATIC, map.getRandX(), map.getRandY() );

	cout << "AI Units... ";
	units.CreateUnit( CMP, (e_unitDir)( (rand() % 7 + 1) ), map.getRandX(), map.getRandY() );
	units.CreateUnit( CMP, (e_unitDir)( (rand() % 7 + 1) ), map.getRandX(), map.getRandY() );
	units.CreateUnit( CMP, (e_unitDir)( (rand() % 7 + 1) ), map.getRandX(), map.getRandY() );

	for (int i = 0; i <= (units.GetUnitVecSize() - 1); i++) {
		if( units.GetUnit(i) == 0 )
			break;

		map.setMap( units.GetUnit(i)->getUnitX(), units.GetUnit(i)->getUnitY(), units.GetUnit(i)->getUnitType() );
	}
	cout <<  "[DONE]" << endl;

	cout << "-=- Game sucessfully loaded -=-" << endl << endl;
}

void Pirates::Think( const int& iElapsedTime )
{
	/** Show the player a highlighted 9x9 grid of selectable tiles.
	 * Don't allow selection of occupied tiles.
	 * If player selects their ship, shoot cannonballs from sides of ship.
	 * Use map.setMap() to clear current location on the map, as well as to set the location to move to.
	 * Use units.GetUnit( ID_in_vec )->moveUnit() to move unit in unit manager.
	 **/
//	thinkPlayer();
}

void Pirates::Render( SDL_Surface* pDestSurface )
{
	/** If game board hasn't changed, grab buffer of current window and blit
	 * that instead of drawing the entire board every single frame **/
	// Render Board
	for ( int i = 0; i < (map.getMapW() + 1); i++ ) {
		for ( int j = 0; j < (map.getMapH() + 1); j++ ) {
			if( map.getMapVal( i, j ) == WATER )
				ApplySurface( pixel_Loc(i), pixel_Loc(j), tiles, pDestSurface, &the_tile_clip[ WATER ] );
		}	// for
	}	// for
	
	// Render Units
	for (int i = 0; i <= (units.GetUnitVecSize() - 1); i++) {
		if( units.GetUnit(i)->getUnitType() == PLY || units.GetUnit(i)->getUnitType() == CMP ) {
			ApplySurface( pixel_Loc(units.GetUnit(i)->getUnitX()), pixel_Loc(units.GetUnit(i)->getUnitY()), ship, pDestSurface, &the_ship_clip[ ( units.GetUnit(i)->getUnitDir() % 4 ) ] );
			ApplySurface( pixel_Loc(units.GetUnit(i)->getUnitX()), pixel_Loc(units.GetUnit(i)->getUnitY()), mast, pDestSurface, &the_mast_clip[ ( units.GetUnit(i)->getUnitType() - 4 ) ] );
		} else {
			ApplySurface( pixel_Loc(units.GetUnit(i)->getUnitX()), pixel_Loc(units.GetUnit(i)->getUnitY()), tiles, pDestSurface, &the_tile_clip[ units.GetUnit(i)->getUnitType() ] );
		}
	}
}

void Pirates::KeyDown( const int& iKeyEnum )
{
	switch( states ) {
		case SELTILE:
			switch( iKeyEnum ) {
				case SDLK_LEFT:
					// Left arrow released
					break;
				case SDLK_RIGHT:
					// Right arrow released
					break;
				case SDLK_UP:
					// Up arrow released
					break;
				case SDLK_DOWN:
					// Down arrow released
					break;
			}
			break;
		default:
			break;
	}
}

void Pirates::KeyUp( const int& iKeyEnum )
{
	switch (iKeyEnum) {
		case SDLK_LEFT:
			// Left arrow released
			break;
		case SDLK_RIGHT:
			// Right arrow released
			break;
		case SDLK_UP:
			// Up arrow released
			break;
		case SDLK_DOWN:
			// Down arrow released
			break;
	}
}

void Pirates::End()
{
	SDL_FreeSurface( tiles );
	SDL_FreeSurface( ship );
	SDL_FreeSurface( mast );
}


void Pirates::thinkPlayer()
{
	return;
}

bool Pirates::Collision( int x, int y )
{
	// Check board boundaries
	if( map.isMapBorder( x, y ) ) {
		cout << "Collision..." << endl;
		return true;
	}
	
	// Check tile types
//	TileVal = (tileKey)map.getMapVal( x, y );
	
	switch( (e_unitID)map.getMapVal( x, y ) ) {
		case PLY:
			return true;
			break;
		case ISL:
			return true;
			break;
		case PRT:
			return true;
			break;
		case CMP:
			return true;
			break;
		default: return false;
	}

	return false;
}
